package com.sd.repay.transfer;

import com.sd.repay.common.CommonResult;
import com.sd.repay.pojo.TransferChannelInfo;
import com.sd.repay.pojo.TransferOrder;
import com.sd.repay.pojo.TransferRoute;
import com.sd.repay.transfer.bank.BaseRepayService;
import com.sd.repay.transfer.bank.CJPayService;
import com.sd.repay.transfer.bank.YPTPayService;
import com.sd.repay.transfer.bank.YunAccountPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;


/**
 * 出款渠道路由
 * <p>
 * <p>
 * 出款渠道路由规则将在这里描述
 *
 * @author 老.A
 */
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Service
public class BaseBankRouteService {

    private Logger log = LoggerFactory.getLogger(BaseBankRouteService.class);

    private Map<String, Object> channelServiceMap = new HashMap<>();

    @Autowired
    private TransferService transferService;

    @Resource
    private YPTPayService yptPayService;

    @Resource
    private CJPayService cjPayService;

    @Resource
    private YunAccountPayService yunAccountPayService;

    /**
     * 初始化渠道信息
     * <p>
     * <p>
     * 渠道对应的Key与trade_source对应
     */
    private void intBaseBankRouteService() {
        channelServiceMap.put("ypt_pay", yptPayService);
        channelServiceMap.put("cj_pay", cjPayService);
        channelServiceMap.put("yun_pay", yunAccountPayService);
    }


    /**
     * 获取渠道
     *
     * @param payBankNo
     * @return
     */
    private BaseRepayService getPayChannel(String payBankNo) {
        BaseRepayService baseRepayService = null;
        if (channelServiceMap.isEmpty()) {
            intBaseBankRouteService();
        }

        Object serviceObj = channelServiceMap.get(payBankNo);
        if (serviceObj == null) {
            return baseRepayService;
        }

        try {
            baseRepayService = (BaseRepayService) serviceObj;
        } catch (Exception e) {
            log.error("获取代付通道出现异常， {}是个未知的代付通道 Service, 异常:{}", serviceObj, e.getMessage());
            return baseRepayService;
        }

        return baseRepayService;
    }


    /**
     * 获取交易路由
     * <p>
     * <p>
     * 规则：<br/>
     * 1.若trade_source指定了通道和出款账户，则此为优先。<br/>
     * 2.若trade_source指定了通道未具体出款账户，则trade_source对应的出款渠道编码相同且状态为正常的优先。<br/>
     * 3.若trade_source未指定任何通道，则trade_source对应的出款渠道编码相同且状态为正常的优先。
     *
     * @param transferOrder 出款明细
     * @return BaseRepayService
     */
    private CommonResult getTransferRoute(TransferOrder transferOrder) {
        CommonResult result = new CommonResult();

        try {
            String outPayBank = "";
            String trade_source = transferOrder.getTradeSource();

            TransferRoute transferRoute = transferService.getTransferRoute(trade_source);
            if (transferRoute != null) {
                log.info("出款明细[{}] 获取到指定出款渠道信息[{}]", transferOrder.toJsonString(), transferRoute.toJsonString());
                outPayBank = transferRoute.getOutPayBank();
            }


            TransferChannelInfo transferChannelInfo = transferService.getTransferChannelInfo(outPayBank);

            if (transferChannelInfo == null) {
                result.setStatus(2);
                result.setMsg("出款通道不存在");
                return result;
            }

            String outAccNo = transferChannelInfo.getBankMerchantNo();
            transferOrder.setOutPayBank(outPayBank);
            transferOrder.setOutAccNo(outAccNo);
            result.setStatus(1);

        } catch (Exception e) {
            result.setStatus(2);
            result.setMsg("交易路由出现错误");
            return result;
        }

        return result;
    }


    /**
     * 初始化并交易
     *
     * @param subOrder
     * @return
     */
    public TransferOrder pay(TransferOrder subOrder) {
        CommonResult routeResult = getTransferRoute(subOrder);
        TransferOrder returnOrder = new TransferOrder();


        if (routeResult.getStatus() == 2) {
            returnOrder.setStatus(routeResult.getStatus() + "");
            returnOrder.setSubResultMsg(routeResult.getMsg());
            return returnOrder;
        }


        BaseRepayService baseRepayService = getPayChannel(subOrder.getOutPayBank());
        if (baseRepayService == null) {
            returnOrder.setStatus("2");
            returnOrder.setSubResultMsg("未找到交易通道");
            return returnOrder;
        }


        long orderId = 0;
        try {
            orderId = transferService.saveTransferOrder(subOrder);
        } catch (Exception e) {
            log.error("请求出款明细[{}] 初始化订单信息发生异常：{}", subOrder.toJsonString(), e.getMessage());
            returnOrder.setStatus("2");
            returnOrder.setSubResultMsg("订单初始化发生错误");
            return returnOrder;
        }


        if (orderId == 0) {
            returnOrder.setStatus("2");
            returnOrder.setSubResultMsg("初始化订单出现错误");
            return returnOrder;
        }


        TransferOrder saveOrder = transferService.getTransferOrderById(orderId + "", "0");
        if (saveOrder == null) {
            returnOrder.setStatus("6");
            returnOrder.setSubResultMsg("订单状态发生改变");
            return returnOrder;
        }

        CommonResult result = baseRepayService.channelCheck(saveOrder);
        if (result.getStatus() == 2) {
            returnOrder.setStatus("2");
            returnOrder.setSubResultMsg(result.getMsg());
            return returnOrder;
        }
        baseRepayService.transferOrder(saveOrder);
        int count = 0;
        try {
            count = transferService.modifySubStaTransfer(saveOrder);
        } catch (Exception e) {
            log.error("出款渠道[{}]订单号[{}] 修改出款状态出现异常:{}", saveOrder.getOutPayBank(), saveOrder.getSubOrderNo(), e.getMessage());
        }
        Object[] objArry = new Object[]{saveOrder.getOutPayBank(), saveOrder.getSubOrderNo(), saveOrder.getStatus(), saveOrder.getSubResultCode(), saveOrder.getSubResultMsg(), count};
        log.info("出款渠道[{}]订单号[{}] 提交状态[{}],渠道响应码[{}], 响应描述[{}],[{}]条记录受到影响", objArry);
        return saveOrder;
    }


    /**
     * 同步代付结果
     *
     * @param order
     */
    public void sysTransferOrderStatus(TransferOrder order) {
        BaseRepayService baseRepayService = getPayChannel(order.getOutPayBank());
        if (baseRepayService == null) {
            log.info("同步代付订单[{}], 未找到可用渠道", order.toJsonString());
            return;
        }
        baseRepayService.queryTransferStatus(order);
        int count = 0;
        try {
            count = transferService.modifySysStaTransfer(order);
        } catch (Exception e) {
            log.error("代付同步状态出现异常，回写代付订单状态失败：{}", order.toJsonString(), count);
        }
        log.info("出款订单号[{}] 同步结果[{}], 渠道响应[{}：{}], [{}]条记录受到影响", new Object[]{order.getSubOrderNo(), order.getStatus(), order.getResultCode(), order.getResultMsg(), count});
    }

}
